package fr.mywiki.business.account;

import java.rmi.RemoteException;
import java.util.ArrayList;

import javax.ejb.FinderException;

import fr.mywiki.business.profil.Profile;
import fr.mywiki.business.structure.StructureLite;
import fr.mywiki.business.utils.MD5;
import fr.mywiki.model.ejbAdapter.EntityHomeCache;
import fr.mywiki.model.ejbAdapter.ServicesFacade;
import fr.mywiki.model.ejbAdapter.entity.AccountLocal;
import fr.mywiki.model.ejbAdapter.utils.PersistenceException;

/**
 * Contains several methods dealing with members of the application.
 * 
 * @author tlombard
 */
public class AccountManager {
	private AccountManager() {}
	
	/**
	 * Returns the account whose login is the one given in parameter.
	 * 
	 * @param login a <code>String</code> object.
	 * @return a <code>AccountLite</code> object of null if no account was found.
	 * @throws FinderException
	 */
	public static AccountLite findAccount(String login) {
		ArrayList possibleAccounts;
		try {
			possibleAccounts = new ArrayList(EntityHomeCache.getInstance()
					.getAccountHome().findByLogin(login));
		} catch (FinderException e) {
			return null;
		}
		if (possibleAccounts.isEmpty())
			return null;
		return ((AccountLocal) possibleAccounts.get(0)).getAccountLite();
	}
	
	/**
	 * Creates an account with login, password and profile given in parameters.
	 * 
	 * @param login the login of the account.
	 * @param password the password, not yet coded.
	 * @param profile the profile of the account.
	 * @param structure the structure where the account is positionned
	 * @return the created account.
	 */
	public static AccountLite createAccount(String login, String password, Profile profile, StructureLite structure)
			throws PersistenceException, RemoteException, FinderException {
		AccountLite account = (AccountLite) ServicesFacade.getInstance()
				.create(AccountLite.TYPE_ENT);
		account.setLogin(login);
		account.setPassword(MD5.asHex(password.getBytes()));
		account.setProfile(profile);
		account.update();
		setStructure(account,structure);

		return account;
	}
	
	/**
	 * Modifies the account given in parameter.
	 * 
	 * @param account
	 *          the <code>AccountLite</code> object to modify.
	 * @param profile
	 *          the profile of the user.
	 * @param login
	 *          the new login of the account.
	 * @param structure
	 *          the structure where the account is positionned
	 */
	public static void modifyAccount(AccountLite account, String login,
			Profile profile, StructureLite structure) throws RemoteException, FinderException {
		account.setLogin(login);
		account.setProfile(profile);
		setStructure(account,structure);

		account.update();
	}
	
	/**
	 * Returns the structure linked to this account.
	 * 
	 * @param account
	 *          a <code>AccountLite</code> object.
	 * @return a <code>StructureLite</code> object, eventually null if the
	 *         account is not linked to a structure.
	 */
	public static StructureLite getStructure(AccountLite account)
			throws RemoteException, FinderException {
		ArrayList links = new ArrayList(ServicesFacade.getInstance().getLinks(
				account, AccountLite.LINK_ACCOUNT_STRUCTURE));
		return (StructureLite) links.get(0);
	}
	
	/**
	 * Sets the structure linked to an account.
	 * 
	 * @param account
	 *          a <code>AccountLite</code> object.
	 * @param structure
	 *          a <code>StructureLite</code> object
	 */
	public static void setStructure(AccountLite account, StructureLite structure) throws RemoteException, FinderException {
		ServicesFacade.getInstance().addLink(account, structure,
				AccountLite.LINK_ACCOUNT_STRUCTURE);
	}
}
